// [参考: 廖雪峰 Promise]()
//================================================================
// 传统的回调
function callback() { console.log('Done'); }
setTimeout(callback, 100); // 0.1 秒钟后调用 callback 函数
console.log('after setTimeout()');
//================================================================
// Promise
function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    console.log('set timeout to: ' + timeOut + ' seconds.');
    setTimeout(function () {
        if (timeOut < 1) { resolve('200 OK'); }
        else { reject('timeout in ' + timeOut + ' seconds.'); }
    }, timeOut * 100);
}
// test() 函数只关心自身的逻辑, 并不关心具体的 resolve 和 reject 将如何处理结果
new Promise(test).then(function (result){  // test 接收两个参数, 这里的 Promise 也传递两个参数
    console.log('成功：' + result);
}).catch(function (reason){
    console.log('失败：' + reason);
});
//================================================================
// 优雅的 Promise
// Promise 还可以做更多的事情, 比如, 有若干个异步任务, 需要先做任务1, 如果成功后再做任务2, 任何任务失败则不再继续并执行错误处理函数
// 要串行执行这样的异步任务, 不用 Promise 需要写一层一层的嵌套代码. 有了 Promise, 我们只需要简单地写:
// job1.then(job2).then(job3).catch(handleError);  // 其中, job1、job2 和 job3 都是 Promise 对象
function multiply(input) {  // 0.5 秒后返回 input * input 的计算结果:
    return new Promise(function (resolve, reject) {
        console.log('calculating ' + input + ' x ' + input + '...');
        setTimeout(resolve, 500, input * input);
    });
}
function add(input) {  // 0.5 秒后返回 input + input 的计算结果:
    return new Promise(function (resolve, reject) {
        console.log('calculating ' + input + ' + ' + input + '...');
        setTimeout(resolve, 500, input + input);
    });
}
var p = new Promise(function (resolve, reject) {
    console.log('start new Promise...');
    resolve(123);
});
p.then(multiply)
 .then(add)
 .then(multiply)
 .then(add)
 .then(function (result) {
    console.log('Got value: ' + result);
});
//================================================================
// all() 并行执行; 要从两个不同的URL分别获得用户的个人信息和好友列表, 这两个任务是可以并行执行的
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); });
var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); });
// 同时执行 p1 和 p2, 并在它们都完成后执行 then
Promise.all([p1, p2]).then(function (results) { console.log(results); });  // 获得一个Array: ['P1', 'P2']
//================================================================
// race() 异步任务是为了容错, 比如, 同时向两个 URL 读取用户的个人信息, 只需要获得先返回的结果即可
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); });
var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); });
Promise.race([p1, p2]).then(function (result) { console.log(result); });  // 'P1'
